#include "show_hide_layer_cell.h"
#include "../../layout/layout.hpp"
#include "../../undoRedo/undoRedo.hpp"
#include "../../utils/kutils.h"

//#include "shader.h"
#include "../../utils/shader.h"

namespace qbe::ShowHideLayerCell {
void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {
  auto options = query.get_resource<vsg::ref_ptr<vsg::Options>>();
  for (auto [e, tran] : reg.view<render::SceneTag, vsg::ref_ptr<vsg::MatrixTransform>>().each()) {
    auto vertices = vsg::vec2Array::create(4);
    (*vertices)[0] = vsg::vec2(0, 0);
    (*vertices)[1] = vsg::vec2(1000, 0);
    (*vertices)[2] = vsg::vec2(1000, 1000);
    (*vertices)[3] = vsg::vec2(0.0, 1000);
    vertices->properties.dataVariance = vsg::DYNAMIC_DATA;

    auto indexs = vsg::uintArray::create(8);
    (*indexs)[0] = 0;
    (*indexs)[1] = 1;
    (*indexs)[2] = 1;
    (*indexs)[3] = 2;
    (*indexs)[4] = 2;
    (*indexs)[5] = 3;
    (*indexs)[6] = 3;
    (*indexs)[7] = 0;
    vertices->properties.dataVariance = vsg::DYNAMIC_DATA;

    utils::TempRender::Mesh2D mesh(vertices, indexs);
    utils::TempRender::LineShaderMaterial2D material{
        utils::TempRender::Line_Uniform{vsg::vec4(1.0, 0.0, 0.0, 1.0), vsg::vec2(1316.0, 847.0), 100.0, 70.0, true}, "shaders/cell/line.vert.spv",
        "shaders/cell/line.frag.spv"};
    auto node =
        utils::TempRender::LineMeshNode::create(options, qlib::Tag{0, 0}, mesh, material, VkPrimitiveTopology::VK_PRIMITIVE_TOPOLOGY_LINE_LIST);
    node->setLayerType(vsg::vec4(1.0, 0.0, 0.0, 1.0), "B1");
    // 创建 Switch
    auto switchObject = vsg::Switch::create();
    tran->addChild(switchObject);
    switchObject->addChild(false, node);
    commands.spawn(TopBoxTag{}, mesh, node, switchObject);
  }
}
void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus, ecs::EventWriter<msg::RenderEvent> event) {
  auto& param = query.get_resource<ShowHideLayerCellModel>();
  auto& cmd = query.get_resource<layout::CellCmd>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  auto current_cell = cmd.cell;

  auto top_cell_func = [&ecs_reg, &current_cell, &layout_cmd, &param]() {
    for (auto [e, node] : ecs_reg.view<TopBoxTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      node->setAllChildren(true);
    }
    for (auto [e, mh] : ecs_reg.view<TopBoxTag, utils::TempRender::Mesh2D>().each()) {
      auto& v = mh.vertices;
      auto bb = current_cell->bounding_box();
      (*v)[0] = vsg::vec2(bb[0].x, bb[0].y);
      (*v)[1] = vsg::vec2(bb[0].x, bb[1].y);
      (*v)[2] = vsg::vec2(bb[1].x, bb[1].y);
      (*v)[3] = vsg::vec2(bb[1].x, bb[0].y);
      v->dirty();
    }
    auto all_entity = auxiliary::getCellAllGraph(current_cell);
    param.grpahs = auxiliary::getGraph(current_cell, all_entity);
    for (auto e : all_entity) {
      {
        auto ptr = current_cell->reg.try_get<qlib::Polygon::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Polygon::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Circle::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Circle::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Ellipse::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Ellipse::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Rectangle::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Rectangle::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Fan::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Fan::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Path::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Path::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Label::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Label::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::KeyPoint::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::KeyPoint::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Pin::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Pin::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Text::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Text::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Reference::s_ptr>(e);
        if (ptr) {
          layout_cmd.remove<qlib::Reference::s_ptr>(e);
        }
      }
    }
  };

  auto show_all_func = [&ecs_reg, &current_cell, &layout_cmd, &param]() {
    for (auto [e, node] : ecs_reg.view<TopBoxTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      node->setAllChildren(false);
    }
    std::vector<entt::entity> all_entity = auxiliary::AddGraphToCell(current_cell, param.grpahs);
    current_cell->update_tags();
    for (auto e : all_entity) {
      {
        auto ptr = current_cell->reg.try_get<qlib::Polygon::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Polygon::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Circle::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Circle::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Ellipse::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Ellipse::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Rectangle::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Rectangle::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Fan::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Fan::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Path::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Path::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Label::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Label::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::KeyPoint::s_ptr>(e);
        if (ptr) {
          auto key_point = *ptr;
          layout_cmd.add<qlib::KeyPoint::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Pin::s_ptr>(e);
        if (ptr) {
          auto pin = *ptr;
          layout_cmd.add<qlib::Pin::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Text::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Text::s_ptr>(e);
        }
      }

      {
        auto ptr = current_cell->reg.try_get<qlib::Reference::s_ptr>(e);
        if (ptr) {
          layout_cmd.add<qlib::Reference::s_ptr>(e);
        }
      }
    }
  };
  {
    auto res = bus.receive<UiMessage::ShowCell_Mes>();
    if (!res.empty()) {
      auto old_current_cell_state = current_cell->is_hide;

      res[0].cell->is_hide = false;
      param.current_cell = current_cell;
      param.updateShowHide();
      //处理最顶层单元被隐藏
      if (old_current_cell_state == true && current_cell->is_hide == false && param.m_display_level != 0) {
        show_all_func();
      }

      current_cell->ref_cache_reg.clear();
      // 缓存 reference
      std::unordered_map<std::string, bool> done_cell_map;
      std::unordered_map<std::string, std::shared_ptr<qlib::Cell>> depend_cell_map = {};
      current_cell->dependencies(true, depend_cell_map);
      for (auto& [name, t_cell] : depend_cell_map) {
        if (done_cell_map.find(name) != done_cell_map.end())
          continue;
        layout_cmd.add_cell(t_cell);
        done_cell_map[name] = true;
      }
      layout_cmd.render_update();  //确定后版图更新
    }
  }

  {
    auto res = bus.receive<UiMessage::HideCell_Mes>();
    if (!res.empty()) {
      auto old_current_cell_state = current_cell->is_hide;
      res[0].cell->is_hide = true;
      auto current_cell = cmd.cell;
      param.current_cell = current_cell;
      param.updateShowHide();
      if (current_cell->is_hide == true && param.m_display_level != 0) {
        top_cell_func();
      }
      current_cell->ref_cache_reg.clear();
      // 缓存 reference
      std::unordered_map<std::string, bool> done_cell_map;
      std::unordered_map<std::string, std::shared_ptr<qlib::Cell>> depend_cell_map = {};
      current_cell->dependencies(true, depend_cell_map);
      for (auto& [name, t_cell] : depend_cell_map) {
        if (done_cell_map.find(name) != done_cell_map.end())
          continue;
        layout_cmd.add_cell(t_cell);
        done_cell_map[name] = true;
      }
      layout_cmd.render_update();  //确定后版图更新
    }
  }
  {
    auto res = bus.receive<UiMessage::ShowLayer_Mes>();
    if (!res.empty()) {

      auto current_cell = cmd.cell;
      layout_cmd.setDisplayLevel(res[0].index);
      param.current_cell = current_cell;

      if (res[0].index == 0 && current_cell->is_hide == false) {
        top_cell_func();
      }
      if ((param.m_display_level == 0 || res[0].index > 0) && current_cell->is_hide == false) {
        show_all_func();
      }
      param.setDisplayLevel(res[0].index);
      param.updateShowHide();

      current_cell->ref_cache_reg.clear();
      // 缓存 reference
      std::unordered_map<std::string, bool> done_cell_map;
      std::unordered_map<std::string, std::shared_ptr<qlib::Cell>> depend_cell_map = {};
      current_cell->dependencies(true, depend_cell_map);
      for (auto& [name, t_cell] : depend_cell_map) {
        if (done_cell_map.find(name) != done_cell_map.end())
          continue;
        layout_cmd.add_cell(t_cell);
        done_cell_map[name] = true;
      }
      //event.send(msg::RenderEvent{msg::RenderCode::CellUpdate});
      layout_cmd.render_update();  //确定后版图更新
    }
  }
}
void post(entt::registry& reg, ecs::Commands commands, ecs::Query query, ecs::Bus& bus) {}

}  // namespace qbe::ShowHideLayerCell